﻿using System.Net;
using AlibabaCloud.OpenApiClient.Models;
using AlibabaCloud.SDK.Dysmsapi20170525;
using AlibabaCloud.SDK.Dysmsapi20170525.Models;
using Devonline.AspNetCore;
using Devonline.Core;
using Microsoft.Extensions.Logging;

namespace Devonline.CloudService.Aliyun;

/// <summary>
/// 阿里云接口短信发送服务
/// </summary>
public class SmsService : ISmsService<SmsModel>
{
    private readonly ILogger<SmsService> _logger;
    private readonly Client _client;
    public SmsService(ILogger<SmsService> logger, ISmsEndpoint endpoint)
    {
        _logger = logger;
        ArgumentNullException.ThrowIfNull(endpoint.Host);
        ArgumentNullException.ThrowIfNull(endpoint.Id);
        ArgumentNullException.ThrowIfNull(endpoint.Secret);
        _client = new Client(new Config { Endpoint = endpoint.Host, AccessKeyId = endpoint.Id, AccessKeySecret = endpoint.Secret });
    }

    /// <summary>
    /// 阿里云接口发送短信
    /// </summary>
    /// <param name="model">短信内容数据模型</param>
    /// <returns></returns>
    public void Send(SmsModel model)
    {
        _logger.LogInformation("The sms service send sms message content: " + model.ToJsonString());
        var response = _client.SendSms(GetSmsRequest(model));
        switch (response.StatusCode)
        {
            case (int)HttpStatusCode.OK when response.Body.Code == HttpStatusCode.OK.ToString():
                _logger.LogInformation("The sms service send sms message success with code: {code}, message: {message}, and sms content: " + model.ToJsonString(), response.Body.Code, response.Body.Message);
                break;
            default:
                throw new Exception($"The sms service send sms message failed with code: {response.Body.Code}, message: {response.Body.Message}");
        }
    }

    /// <summary>
    /// 阿里云接口发送短信
    /// </summary>
    /// <param name="model">短信内容数据模型</param>
    /// <returns></returns>
    public async Task SendAsync(SmsModel model)
    {
        _logger.LogInformation("The sms service send sms message content: " + model.ToJsonString());
        var response = await _client.SendSmsAsync(GetSmsRequest(model));
        switch (response.StatusCode)
        {
            case (int)HttpStatusCode.OK when response.Body.Code == HttpStatusCode.OK.ToString():
                _logger.LogInformation($"The sms service send sms message success with code: {response.Body.Code}, message: {response.Body.Message}, and sms content: {model.ToJsonString()}");
                break;
            default:
                throw new Exception($"The sms service send sms message failed with code: {response.Body.Code}, message: {response.Body.Message}");
        }
    }

    /// <summary>
    /// 构造发送参数
    /// </summary>
    /// <param name="model">短信内容数据模型</param>
    /// <returns></returns>
    private static SendSmsRequest GetSmsRequest(SmsModel model)
    {
        ArgumentNullException.ThrowIfNull(model.SignName);
        ArgumentNullException.ThrowIfNull(model.TemplateCode);
        ArgumentNullException.ThrowIfNull(model.TemplateParam);
        ArgumentNullException.ThrowIfNull(model.PhoneNumbers);
        var request = new SendSmsRequest
        {
            SignName = model.SignName,
            TemplateCode = model.TemplateCode,
            TemplateParam = model.TemplateParam.ToJsonString(),
            PhoneNumbers = model.PhoneNumbers.ToString<string>()
        };

        return request;
    }
}